package com.fowo.api.sys.service.impl;

import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fowo.api.common.model.RException;
import com.fowo.api.common.util.ListUtils;
import com.fowo.api.config.AppProperties;
import com.fowo.api.sys.annotation.DataActivity;
import com.fowo.api.sys.entity.SysUser;
import com.fowo.api.sys.entity.SysUserPost;
import com.fowo.api.sys.entity.SysUserRole;
import com.fowo.api.sys.entity.SysUserSetting;
import com.fowo.api.sys.entity.enums.SysDataActivityAction;
import com.fowo.api.sys.mapper.*;
import com.fowo.api.sys.model.*;
import com.fowo.api.sys.service.*;
import com.fowo.api.user.model.CurrentUser;
import com.fowo.api.user.model.JwtUserInfo;
import org.apache.commons.collections4.CollectionUtils;
import org.jetbrains.annotations.Nullable;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Primary;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.io.Serializable;
import java.time.Duration;
import java.util.*;

@Service
@Primary
public class SysUserServiceCustomImpl extends SysUserServiceImpl {
    @Resource
    private PasswordEncoder passwordEncoder;
    @Resource
    private SysRoleService roleService;
    @Resource
    private SysUserRoleMapper userRoleMapper;
    @Resource
    private SysUserPostMapper sysUserPostMapper;
    @Resource
    private SysDepartmentMapper sysDepartmentMapper;
    @Resource
    private SysMessageService sysMessageService;
    @Resource
    private SysUserSettingMapper sysUserSettingMapper;
    @Resource
    private AppProperties appProperties;
    @Resource
    private SysUserPermissionShopinfoService sysUserPermissionShopinfoService;
    @Resource
    private SysUserPermissionWarehouseService sysUserPermissionWarehouseService;



    @DataActivity(action = SysDataActivityAction.Modified)
    @Transactional
    @Override
    public boolean update(SysUserVo sysUserVo) {
        if (StringUtils.hasText(sysUserVo.getPassword())) {
            sysUserVo.setPassword(passwordEncoder.encode(sysUserVo.getPassword()));
        }
        sysUserVo.doUpdate();
        if (baseMapper.updateById(sysUserVo) > 0) {
            if (sysUserVo.getRoles() != null) {
                updateRolesByUserId(sysUserVo.getId(), sysUserVo.getRoles());
            }
            if (sysUserVo.getPostsIds() != null) {
                updatePostsByUserId(sysUserVo.getId(), sysUserVo.getPostsIds());
            }
            if (sysUserVo.getDepartmentIds() != null) {
                updateDepartmentsByUserId(sysUserVo.getId(), sysUserVo.getDepartmentIds());
            }
            if (sysUserVo.getDepartmentIds() != null) {
                updateDepartmentsByUserId(sysUserVo.getId(), sysUserVo.getDepartmentIds());
            }
            if (sysUserVo.getShopinfoList() != null) {
                if (Convert.toBool(sysUserVo.getSelectAllShopinfo(), false)) {
                    sysUserVo.setShopinfoList(sysUserPermissionShopinfoService.getAllList(sysUserVo.getId()));
                }
                sysUserPermissionShopinfoService.create(sysUserVo.getId(), sysUserVo.getShopinfoList());
            }
            if (sysUserVo.getWarehouseList() != null) {
                if (Convert.toBool(sysUserVo.getSelectAllWarehouse(), false)) {
                    sysUserVo.setWarehouseList(sysUserPermissionWarehouseService.getAllList(sysUserVo.getId()));
                }
                sysUserPermissionWarehouseService.create(sysUserVo.getId(), sysUserVo.getWarehouseList());
            }
            return true;
        }
        return false;
    }


    private void updateDepartmentsByUserId(Long userId, List<Long> departmentIds) {
        List<Long> oldDepartmentIds = sysDepartmentMapper.getDepartmentIdsByUserId(userId);
        if (CollectionUtils.isEqualCollection(oldDepartmentIds, departmentIds)) {
            // 没有变更，可直接返回
            return;
        }
        sysDepartmentMapper.deleteByUserId(userId);
        for (Long departmentId : departmentIds) {
            sysDepartmentMapper.insertUserDepartment(userId, departmentId);
        }
    }

    private void updatePostsByUserId(Long userId, List<Long> postsIds) {
        List<Long> oldPostsIds = sysUserPostMapper.selectPostIdsByUserId(userId);
        if (CollectionUtils.isEqualCollection(oldPostsIds, postsIds)) {
            // 没有变更，可直接返回
            return;
        }
        sysUserPostMapper.deleteByUserId(userId);
        for (Long postId : postsIds) {
            SysUserPost sysUserPost = new SysUserPost();
            sysUserPost.setUserId(userId);
            sysUserPost.setPostId(postId);
            sysUserPostMapper.insert(sysUserPost);
        }
    }

    private void updateRolesByUserId(Long userId, List<Long> roles) {
        if (roles == null) {
            return;
        }
        userRoleMapper.delete(Wrappers.<SysUserRole>query().eq("user_id", userId));
        for (Long roleId : roles) {
            SysUserRole sysUserRole = new SysUserRole();
            sysUserRole.setUserId(userId);
            sysUserRole.setRoleId(roleId);
            sysUserRole.doCreate();
            userRoleMapper.insert(sysUserRole);
        }
    } 
}
